package com.ldk.api.handler;

import com.ldk.api.ApiVersion;
import com.ldk.api.CheckToken;
import com.ldk.api.Consts;
import com.ldk.api.ErrorCode;
import com.ldk.api.RequestPlatform;
import com.ldk.api.ResponseObject;
import com.ldk.api.ResponseResult;
import com.ldk.base.framework.util.ConvertUtil;
import com.ldk.base.framework.util.SystemUtil;
import com.ldk.framework.entity.Driver;
import com.ldk.framework.entity.ServiceTrip;
import com.ldk.framework.entity.User;
import com.ldk.framework.enums.BillingMode;
import com.ldk.framework.enums.DriverStatus;
import com.ldk.framework.enums.PlatformUserType;
import com.ldk.framework.enums.ServiceCode;
import com.ldk.framework.enums.TripNoType;
import com.ldk.framework.enums.TripStatus;
import com.ldk.framework.service.IAreaService;
import com.ldk.framework.service.ICompanyfareService;
import com.ldk.framework.service.IDictdataService;
import com.ldk.framework.service.IDriverService;
import com.ldk.framework.service.IServiceConfigService;
import com.ldk.framework.service.IUserService;
import com.ldk.framework.service.IZXPCServiceTripService;

import org.apache.commons.lang.StringUtils;
import org.apache.http.util.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

/**
 * 专车业务模块
 *
 * @author mqy
 * 2017年3月4日
 * com.ldk.api.handler
 * ZXPCRequestHandler
 */
public class ZCRequestHandler extends BZBaseRequestHandler {

    @Autowired
    private IUserService userService;
    @Autowired
    private IServiceConfigService serviceConfigService;
    @Autowired
    private ICompanyfareService companyfareService;
    @Autowired
    private IZXPCServiceTripService zXPCServiceTripService;
    @Autowired
    private IDriverService driverService;
    @Autowired
    protected IAreaService areaService;
    @Autowired
    private IDictdataService dictdataService;

    /**
     * 用户发布专车行程
     *
     * @param parms
     * @return
     * @paramopenId 用户openId
     * @paramstartLocation 出发地点
     * @paramstartLon 出发地点经度
     * @paramstartLat 出发地点纬度
     * @paramendLocation 目的地点
     * @paramendLon 目的地点经度
     * @paramendLat 目的地点纬度
     * @paramgoTime 出发时间 时间字符串yyyy-MM-dd HH:mm:ss
     * @paramcrewCount 乘客人数，默认1
     */
    @ApiVersion(value = {1})
    @CheckToken(tokenKey = "openId", platform = RequestPlatform.client)
    public ResponseObject userPublish(Map<String, Object> parms) {
        ResponseObject response = ResponseResult.create("zc", "userPublish");
        //参数检验
        if (!checkRequireParms(parms, "openId", "startLocation",
                "startLon", "startLat", "endLocation", "endLon", "endLat", "goTime", "tripType")) {
            return ResponseResult.exception(response, ErrorCode.REQUEST_PARMS_ERROR);
        }
        String openId = ConvertUtil.parseString(parms.get("openId"));
        String startLocation = ConvertUtil.parseString(parms.get("startLocation"));
        Double startLon = ConvertUtil.parseDouble(parms.get("startLon"));
        Double startLat = ConvertUtil.parseDouble(parms.get("startLat"));
        String endLocation = ConvertUtil.parseString(parms.get("endLocation"));
        Double endLon = ConvertUtil.parseDouble(parms.get("endLon"));
        Double endLat = ConvertUtil.parseDouble(parms.get("endLat"));
        String goTime = ConvertUtil.parseString(parms.get("goTime"));
        Integer crewCount = ConvertUtil.parseInt(parms.get("crewCount"), 1);
        Integer tripType = ConvertUtil.parseInt(parms.get("tripType"), 1);

        crewCount = Math.max(crewCount, 1);
        crewCount = Math.min(crewCount, 4);

        String departTime = ConvertUtil.parseString(parms.get("departTime"));
        String dCommonId = ConvertUtil.parseString(parms.get("dCommonId"));

        //用户openId和司机openId
        if (StringUtils.isBlank(openId)) {
            return ResponseResult.exception(response, ErrorCode.OPENID_EMPTY);
        }

        long ldCommonId = 0;
        long ldepartTime = SystemUtil.stringToSeconds(departTime, "yyyy-MM-dd HH:mm:ss");

        /*if(!StringUtils.isBlank(dCommonId)){
            if(!RegexUtil.isUInt(dCommonId)) {
                return ResponseResult.exception(response, ErrorCode.DCOMMONID_FORMAT_ERROR);
            }
            if((dCommonId.length() !=6 )) {
                return ResponseResult.exception(response, ErrorCode.DCOMMONID_FORMAT_ERROR);
            }
            if (!driverService.existDCommonId(ConvertUtil.parseLong(dCommonId))) {
                return ResponseResult.exception(response, ErrorCode.DRIVER_NOT_EXIST);
            } else {
                ldCommonId = ConvertUtil.parseLong(dCommonId);
                CustomPageable pageable = new CustomPageable(0, 5);

                Driver driverQuery = new Driver();
                driverQuery.setEnabled(true);
                driverQuery.setLon(startLon);
                driverQuery.setLat(startLat);
                driverQuery.setStatus(DriverStatus.OnLine.getValue());

                //搜索指定司机是否在快车行程起点周围
                List<Driver> driverList = driverService.searchByDistance("", driverQuery, 10000, pageable);

                //司机没上线或不在附近区域
                if(driverList == null || driverList.isEmpty()) {
                    return ResponseResult.exception(response, ErrorCode.DRIVER_NOT_EXIST_AREA);
                }
            }
        }*/
        User user = userService.getUserByOpenId("", openId);
        if (user == null) {
            return ResponseResult.exception(response, ErrorCode.USER_NOT_EXIST);
        }
        //判断用户是否已经有了未完成的包车行程
        int status = TripStatus.Publish.getValue()
                //|TripStatus.DepositPayed.getValue()
                | TripStatus.Accept.getValue()
                | TripStatus.Go.getValue()
                | TripStatus.WaitingPerson.getValue()
                | TripStatus.OnTheCar.getValue()
                | TripStatus.OFFTheCar.getValue()
                | TripStatus.WaitingPay.getValue();
        ServiceTrip query = new ServiceTrip();
        query.setServiceCode(ServiceCode.KC.getCode() + "," + ServiceCode.ZC.getCode());
        query.setOpenId(openId);
        query.setUserType(PlatformUserType.CLIENT_USER.getValue());
        query.setStatus(status);

        long count = zXPCServiceTripService.selectCount("", query);
        if (count > 0) {
            return ResponseResult.exception(response, ErrorCode.KC_HAS_NOT_FINISHED_TRIP);
        }
        //出发地点为空
        if (StringUtils.isBlank(startLocation) ||
                startLon == null || startLon == 0 ||
                startLat == null || startLat == 0) {
            return ResponseResult.exception(response, ErrorCode.KC_START_EMPTY);
        }
        //目的地点为空
        if (StringUtils.isBlank(endLocation) ||
                endLon == null || endLon == 0 ||
                endLat == null || endLat == 0) {
            return ResponseResult.exception(response, ErrorCode.KC_END_EMPTY);
        }
        //出发时间为空
        if (StringUtils.isBlank(goTime)) {
            return ResponseResult.exception(response, ErrorCode.KC_GO_TIME_EMPTY);
        }
        Map<String, Object> result = zXPCServiceTripService.estimateFee("", ServiceCode.KC.getCode(), "", 0L, startLon, startLat, endLon, endLat, crewCount, Consts.BAIDU_MAP_AK, Consts.AREA_CODE);
        Boolean success = result.containsKey("success") ? ConvertUtil.parseBoolean(result.get("success")) : false;
        if (!success) {
            return ResponseResult.exception(response, ErrorCode.TRIP_READ_CONFIG_FAILED);
        }
        //转化为
        double distance = result.containsKey("distance") ? ConvertUtil.parseDouble(result.get("distance")) : 0.0;//米
        double duration = result.containsKey("duration") ? ConvertUtil.parseDouble(result.get("duration")) : 0.0;//秒
        //总费用
        double totalFee = result.containsKey("fee") ? ConvertUtil.parseDouble(result.get("fee")) : 0.0;
        //区域编码
        String areaCode = result.containsKey("areaCode") ? ConvertUtil.parseString(result.get("areaCode")) : "";
        //所属公司编码
        String companyId = result.containsKey("companyId") ? ConvertUtil.parseString(result.get("companyId")) : "";

        String tripNo = SystemUtil.generateOrderNo(TripNoType.ZC.getPrefix());
        try {
            Long lGoTime = SystemUtil.stringToSeconds(goTime, "yyyy-MM-dd HH:mm:ss");
            ServiceTrip entity = new ServiceTrip();
            entity.setTripNo(tripNo);
            entity.setServiceCode(ServiceCode.ZC.getCode());
            entity.setUserType(PlatformUserType.CLIENT_USER.getValue());
            entity.setTripType(tripType);
            entity.setOpenId(openId);
            entity.setRoadId(0L);
            entity.setStartLocation(startLocation);
            entity.setStartLon(startLon);
            entity.setStartLat(startLat);
            entity.setEndLocation(endLocation);
            entity.setEndLon(endLon);
            entity.setEndLat(endLat);
            entity.setGoTime(lGoTime);
            entity.setCarRank("");
            entity.setCarSeats(0);//废弃
            entity.setCrewCount(crewCount);
            entity.setCreateTime(SystemUtil.getAllSeconds());
            entity.setStatus(TripStatus.Publish.getValue());
            //单位米
            entity.setDistance(distance);
            //单位秒
            entity.setDuration(duration);
            entity.setHasAsign(false);
            entity.setHasComment(false);
            entity.setBillingMode(BillingMode.Distance.getValue());
            //对费用进行四舍五入
            double tmpPayFee = ConvertUtil.toRoundFiexd(totalFee);
            //double tmpDepositPayFee = ConvertUtil.toRoundFiexd(depositPayFee);
            entity.setPayFee(tmpPayFee);
            //entity.setDepositPayFee(tmpDepositPayFee);

            entity.setCompanyId(companyId);
            entity.setAreaCode(areaCode);

            entity.setdCommonId(ldCommonId);
            entity.setDepartTime(ldepartTime);

            //logger.error("entity serviceId="+entity.getServiceId());
            success = zXPCServiceTripService.publish("", entity);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        if (success) {
            query = new ServiceTrip();
            query.setTripNo(tripNo);
            ServiceTrip trip = zXPCServiceTripService.selectByKey("", query);
            ResponseResult.success(response, trip);
        } else {
            ResponseResult.exception(response, ErrorCode.KC_PUBLISH_TRIP_FAILED);
        }

        return response;
    }


    /**
     * 用户取消专车行程
     *
     * @param parms
     * @return
     * @paramopenId 用户openId
     * @paramtripNo 专车行程单号
     */
    @ApiVersion(value = {1})
    @CheckToken(tokenKey = "openId", platform = RequestPlatform.client)
    public ResponseObject userCancel(Map<String, Object> parms) {
        ResponseObject response = ResponseResult.create("zc", "userCancel");
        //参数检验
        if (!checkRequireParms(parms, "openId", "tripNo")) {
            return ResponseResult.exception(response, ErrorCode.REQUEST_PARMS_ERROR);
        }
        String openId = ConvertUtil.parseString(parms.get("openId"));
        String tripNo = ConvertUtil.parseString(parms.get("tripNo"));
        if (StringUtils.isBlank(openId)) {
            return ResponseResult.exception(response, ErrorCode.OPENID_EMPTY);
        }
        if (StringUtils.isBlank(tripNo)) {
            return ResponseResult.exception(response, ErrorCode.TRIP_NO_EMPTY);
        }
        User user = userService.getUserByOpenId("", openId);
        if (user == null) {
            return ResponseResult.exception(response, ErrorCode.USER_NOT_EXIST);
        }
        //必须是自己的行程
        ServiceTrip query = new ServiceTrip();
        query.setTripNo(tripNo);
        query.setOpenId(openId);
        query.setServiceCode(ServiceCode.ZC.getCode());
        query.setUserType(PlatformUserType.CLIENT_USER.getValue());
        ServiceTrip userTrip = zXPCServiceTripService.selectOne("", query);
        if (userTrip == null) {
            return ResponseResult.exception(response, ErrorCode.TRIP_NOT_EXIST);
        }
        int tripStatus = TripStatus.Publish.getValue()
                //+ TripStatus.DepositPayed.getValue()
                + TripStatus.Accept.getValue();
        //能取消的行程状态值(发布，支付定金，接单，上车)
        if ((userTrip.getStatus() & tripStatus) != userTrip.getStatus()) {
            return ResponseResult.exception(response, ErrorCode.STATUS_ERROR);
        }
        //获取出租车的配置信息
        /*ServiceConfig configQuery = new ServiceConfig();
        configQuery.setServiceCode(ServiceCode.KC.getCode());
        configQuery.setEnabled(true);
        ServiceConfig config = serviceConfigService.selectOne("", configQuery);
        KCServiceOtherConfig kcConfig = new KCServiceOtherConfig();
        if (config != null && !StringUtils.isBlank(config.getOtherConfig())) {
            kcConfig = JSON.parseObject(config.getOtherConfig(), KCServiceOtherConfig.class);
        }
        //多少分钟内免费取消
        int freeCancelMinute = kcConfig.getFreeCancelMinute() == null ? 3 : kcConfig.getFreeCancelMinute();
        freeCancelMinute = freeCancelMinute * 60;
        long currentTime = SystemUtil.getAllSeconds();
        long createTime = userTrip.getCreateTime();
        Boolean freeCancel = false;
        if ((createTime + freeCancelMinute) >= currentTime) {
            freeCancel = true;
        }*/
        Boolean success = false;
        try {
            success = zXPCServiceTripService.userCancel("", userTrip, user, true);
        } catch (Exception e) {
            logger.error("kc.userCancel.error=" + e.getMessage());
        }
        if (success) {
            query = new ServiceTrip();
            query.setTripNo(tripNo);
            ServiceTrip result = zXPCServiceTripService.selectByKey("", query);
            response = ResponseResult.success(response, result);
        } else {
            response = ResponseResult.exception(response, ErrorCode.KC_USER_CANCEL_TRIP_FAILED);
        }
        return response;
    }

    /**
     * 司机接受专车行程
     *
     * @param parms
     * @return
     * @paramopenId 司机openId
     * @paramtripNo 用户行程号
     */
    @ApiVersion(value = {1})
    @CheckToken(tokenKey = "openId", platform = RequestPlatform.driver)
    public ResponseObject driverAccept(Map<String, Object> parms) {
        //logger.error("ycs driverAccept...");
        ResponseObject response = ResponseResult.create("zc", "driverAccept");
        //参数检验
        if (!checkRequireParms(parms, "openId", "tripNo")) {
            return ResponseResult.exception(response, ErrorCode.REQUEST_PARMS_ERROR);
        }
        String openId = ConvertUtil.parseString(parms.get("openId"));
        String tripNo = ConvertUtil.parseString(parms.get("tripNo"));
        if (StringUtils.isBlank(openId)) {
            return ResponseResult.exception(response, ErrorCode.OPENID_EMPTY);
        }
        if (StringUtils.isBlank(tripNo)) {
            return ResponseResult.exception(response, ErrorCode.TRIP_NO_EMPTY);
        }
        //判断司机是否存在
        Driver driver = driverService.getDriverByOpenId("", openId);
        if (driver == null) {
            return ResponseResult.exception(response, ErrorCode.DRIVER_NOT_EXIST);
        }
        //接行程的司机状态条件
        if (driver.getStatus() != DriverStatus.OnLine.getValue()) {
            return ResponseResult.exception(response, ErrorCode.DRIVER_STATUS_NOT_ONLINE);
        }

        //判断司机是否有发布的顺风车行程
        ServiceTrip driverTripQuery = new ServiceTrip();
        driverTripQuery.setOpenId(openId);
        driverTripQuery.setStatus(TripStatus.Publish.getValue());
        driverTripQuery.setServiceCode(ServiceCode.ZC.getCode());
        driverTripQuery.setUserType(PlatformUserType.DRIVER_USER.getValue());
        ServiceTrip driverTrip = zXPCServiceTripService.selectOne("", driverTripQuery);
        if(driverTrip == null){
            return ResponseResult.exception(response, ErrorCode.TRIP_NOT_EXIST);
        }

        //用户行程必须存在
        ServiceTrip userTripQuery = new ServiceTrip();
        userTripQuery.setTripNo(tripNo);
        userTripQuery.setUserType(PlatformUserType.CLIENT_USER.getValue());
        userTripQuery.setServiceCode(ServiceCode.ZC.getCode());

        ServiceTrip userTrip = zXPCServiceTripService.selectOne("", userTripQuery);
        if (userTrip == null) {
            return ResponseResult.exception(response, ErrorCode.TRIP_NOT_EXIST);
        }
        // 能接收的行程状态值(发布,定金支付)
		/*if (userTrip.getStatus() != TripStatus.DepositPayed.getValue()) {
			return ResponseResult.exception(response, ErrorCode.STATUS_ERROR);
		}*/
        if (userTrip.getStatus() != TripStatus.Publish.getValue()) {
            return ResponseResult.exception(response, ErrorCode.STATUS_ERROR);
        }
        Boolean success = false;
        try {
            userTrip.setDriverOpenId(openId);//设置行程接单司机openId
            success = zXPCServiceTripService.driverAccept("", userTrip,driverTrip);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        if (success) {
            //接单成功后，查询司机订单信息
            //response = ResponseResult.success(response, userTrip);
            ServiceTrip query = new ServiceTrip();
            query.setTripNo(driverTrip.getTripNo());
            ServiceTrip result = zXPCServiceTripService.selectByKey("", query);
            response = ResponseResult.success(response, result);
        } else {
            response = ResponseResult.exception(response, ErrorCode.KC_DRIVER_ACCEPT_FAILED);
        }

        return response;
    }

}
